package com.spzx.product.controller;



import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageHelper;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.core.web.controller.BaseController;
import com.spzx.common.core.web.domain.AjaxResult;
import com.spzx.common.core.web.page.TableDataInfo;
import com.spzx.product.api.vo.ProductSkuVo;
import com.spzx.product.api.vo.SkuPriceVo;
import com.spzx.product.domain.Product;
import com.spzx.product.domain.ProductSku;
import com.spzx.product.query.SkuQuery;
import com.spzx.product.service.*;
import com.spzx.product.vo.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author LOGIN
 * @title ChannelController
 * @create 2025/7/23 19:19
 * @description
 */
@Slf4j
@Tag(name="聚合数据")
@RestController
@RequestMapping("/channel")
public class ChannelController extends BaseController {

    @Autowired
    private ICategoryService categoryService;
    @Autowired
    private IProductSkuService productSkuService;
    @Autowired
    private IBrandService brandService;
    @Autowired
    private ISkuStockService skuStockService;
    @Autowired
    private IProductDetailsService productDetailsService;
    @Autowired
    private IProductService productService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;


    @Operation(summary = "获取首页数据")
    @GetMapping("/index")
    public AjaxResult index(){
        List<CategoryVo> levelOneCategory = categoryService.getLevelOneCategory();
        List<ProductSkuVo> topSale = productSkuService.getTopSale();
        IndexDataVo indexDataVo = new IndexDataVo();
        indexDataVo.setCategoryList(levelOneCategory);
        indexDataVo.setProductSkuList(topSale);
        return success(indexDataVo);
    }
    @Operation(summary = "获取分类页嵌套列表")
    @GetMapping("/category")
    public AjaxResult category(){
        return success(categoryService.tree());
    }

    @Operation(summary = "显示商品列表")
    @GetMapping("/skuList/{pageNum}/{pageSize}")
    public TableDataInfo skuList(
            @Parameter(description = "页码")
            @PathVariable Integer pageNum,
            @Parameter(description = "页大小")
            @PathVariable Integer pageSize,
            SkuQuery skuQuery
    ){
        //这行代码的作用是对后续通过 productSkuService.selectProductList(skuQuery) 查询出的商品 SKU 列表进行分页处理。
        PageHelper.startPage(pageNum,pageSize);
        List<ProductSkuVo> list = productSkuService.selectProductList(skuQuery);
        return getDataTable(list);
    }

    @Operation(summary = "查询所有品牌")
    @GetMapping("/brand")
    public AjaxResult selectBrand(){
        return success(brandService.list());
    }
    @Operation(summary = "查询所有品牌")
    @GetMapping("/item/{skuId}")
    public AjaxResult item(
            @Parameter(description = "商品SKU ID")
            @PathVariable Long skuId
    ){
        //先查询bitmap 中的skuId
        Boolean result = redisTemplate.opsForValue().getBit("product:sku:ids", skuId);
        if(!result){ //id在bitmap 中不存在
            log.error("商品不存在");
            throw new ServiceException("商品不存在");
        }
        //todo
        ItemVo itemVo = new ItemVo();
        CompletableFuture<Long> productSkuFuture = CompletableFuture.supplyAsync(() -> {
            //1、根据skuId查询productSKU信息
            ProductSku productSku = productSkuService.getProductSkuById(skuId);
            itemVo.setProductSku(productSku);
            Long productId = productSku.getProductId();//todo productId
            return productId;
        }, threadPoolExecutor);

        //todo 如下2、3 和 1、为并发执行。1、先执行，2、3、再执行 ,
        CompletableFuture<Void> skuPriceFuture = CompletableFuture.runAsync(() -> {
            //2、根据skuId查询productSKU价格
            SkuPriceVo skuPrice = productSkuService.getSkuPrice(skuId);
            itemVo.setSkuPrice(skuPrice);
        });
        CompletableFuture<Void> skuStockFuture = CompletableFuture.runAsync(() -> {
            //3、根据skuId查询skuSKU库存
            SkuStockVo skuStock = skuStockService.getSkuStock(skuId);
            itemVo.setSkuStock(skuStock);
        });


        // todo 如下逻辑，productId需从1、中获取，因此与1、是串行
        CompletableFuture<Void> productDetailsFuture = productSkuFuture.thenAcceptAsync(productId -> {
            //4、根据productId查询商品详情图片
            String[] productDetails = productDetailsService.getDetailsImageUrlList(productId);
            itemVo.setDetailsImageUrlList(productDetails);
        });
        CompletableFuture<Void> productFuture = productSkuFuture.thenAcceptAsync(productId -> {
            //5、根据productId查询product
            Product product = productService.getById(productId);
            String[] split = product.getSliderUrls().split(",");
            itemVo.setSliderUrlList(split);
            //商品信息:商品规格列表
            JSONArray SpecValueList = JSON.parseArray(product.getSpecValue());
            itemVo.setSpecValueList(SpecValueList);
        });
        CompletableFuture<Void> skuSpecValueMapFuture = productSkuFuture.thenAcceptAsync(productId -> {
            //6、商品规格对应商品SKU ID
            Map<String, Long> skuSpecValueMap = productSkuService.getSkuSpecValue(productId);
            itemVo.setSkuSpecValueMap(skuSpecValueMap);
        });

        CompletableFuture.allOf(
                productFuture,
                productSkuFuture,
                skuSpecValueMapFuture,
                skuPriceFuture,
                skuStockFuture,
                productDetailsFuture
        ).join();
        return success(itemVo);
    }




}
